package base

import (
	"hi-jvm/instructions/base"
	"hi-jvm/rtda"
	"math"
)

/*
数学指令包括算术指令，位移指令，布尔运算指令等，共37条指令
 */

/*
算术指令分为加(add)，减(sub)，乘(mul)， 除(div)， 求余(rem)， 取反(neg) 6中指令
 */

/**
 本文件中为求余
 */

// Remainder double
// 指令码：0x73
type DREM struct{ base.NoOperandsInstruction }
// Remainder float 指令码：0x70
type FREM struct{ base.NoOperandsInstruction }
// Remainder int 指令码：0x71
type IREM struct{ base.NoOperandsInstruction }
// Remainder long 指令码：0x72
type LREM struct{ base.NoOperandsInstruction }

func (self *DREM) Execute(frame *rtda.Frame) {
	stack := frame.OperandStack
	v2 := stack.PopDouble()
	v1 := stack.PopDouble()
	result := math.Mod(v1, v2) // todo
	stack.PushDouble(result)
}

func (self *FREM) Execute(frame *rtda.Frame) {
	stack := frame.OperandStack
	v2 := stack.PopFloat()
	v1 := stack.PopFloat()
	result := float32(math.Mod(float64(v1), float64(v2))) // todo
	stack.PushFloat(result)
}

func (self *IREM) Execute(frame *rtda.Frame) {
	stack := frame.OperandStack
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	if v2 == 0 {
		panic("java.lang.ArithmeticException: / by zero")
	}

	result := v1 % v2
	stack.PushInt(result)
}

func (self *LREM) Execute(frame *rtda.Frame) {
	stack := frame.OperandStack
	v2 := stack.PopLong()
	v1 := stack.PopLong()
	if v2 == 0 {
		panic("java.lang.ArithmeticException: / by zero")
	}

	result := v1 % v2
	stack.PushLong(result)
}